home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 1122 / 1122.xpi / chrome / tabmixplus.jar / content / tabmixplus / tabmix.js < prev    next >
Text File  |  2009-10-11  |  41KB  |  943 lines

  1. /*
  2.  * tabmix.js
  3.  *
  4.  * original code by Hemiola SUN, further developed by onemen and CPU
  5.  */
  6. var gIsFirefox35;
  7. var gIsFirefox36;
  8. var gIsFirefox37;
  9. // when bug 347930 landed replace gisToolbarMode with gIsFirefox(XX)
  10. var gisToolbarMode;
  11.  
  12. function TM_init() {
  13.   document.getElementById("goPopup").addEventListener("popupshowing", TMP_Places.historyMenuItemsTitle, false);
  14.   // history menu open in new tab if the curren tab is locked
  15.   var historyMenu = document.getElementById("goPopup").parentNode;
  16.   if (historyMenu)
  17.     historyMenu.setAttribute("oncommand", "TMP_Places.historyMenu(event);");
  18.  
  19.   // disable the "Open New Window action in Single Window Mode...
  20.   var cmdNewWindow = document.getElementById("cmd_newNavigator");
  21.   var originalNewNavigator = cmdNewWindow.getAttribute("oncommand");
  22.   cmdNewWindow.setAttribute("oncommand","if (gSingleWindowMode) BrowserOpenTab(); else {" + originalNewNavigator + "}");
  23.  
  24.   // replace browser handlers with ours so it recognizes when tabs are acted on
  25.   gBrowser.onTabBarDblClick = TM_onTabBarDblClick;
  26.   gBrowser.onTabClick = TM_checkClick;
  27.  
  28.   if(gBrowser.moveTabTo)
  29.     gBrowser.moveTabTo = gBrowser.TMmoveTabTo;
  30.  
  31.   gBrowser.closedTabs = [];
  32.  
  33.   gBrowser.onresize = tabBarWidthChange;
  34.   document.getElementById("contentAreaContextMenu").addEventListener("popupshowing", TM_checkContentMenu, false);
  35.  
  36.   // override some of All-in-One Gestures function
  37.   // override the duplicate tab function
  38.   if (typeof aioDupTab == 'function')
  39.     aioDupTab = function() { gBrowser.duplicateTab(gBrowser.mCurrentTab); };
  40.  
  41.   //override the duplicate in new window function
  42.   if (typeof aioDupWindow == 'function')
  43.     aioDupWindow = function() { gBrowser.duplicateInWindow(gBrowser.mCurrentTab); };
  44.  
  45.   //override the aioCloseWindow function
  46.   if (typeof aioCloseWindow == 'function')
  47.     aioCloseWindow = BrowserTryToCloseWindow;
  48.  
  49.   window.setTimeout(TMP_delayedStartup, 0);
  50.  
  51.   //Browser:Home open in new tab if the curren tab is locked
  52.   window.BrowserHome = TM_BrowserHome;
  53.  
  54.   // add call to TMP_Sanitizer
  55.   // nsBrowserGlue.js use loadSubScript to load Sanitizer so we need to add this here
  56.   var cmd = document.getElementById("Tools:Sanitize");
  57.   if (cmd)
  58.     cmd.setAttribute("oncommand", cmd.getAttribute("oncommand") + " TMP_Sanitizer.tryToSanitize();");
  59.  
  60.   // if sessionStore disabled use TMP command
  61.   window.undoCloseTab = function ct_window_undoCloseTab(aIndex, aWhere) {
  62.     return TMP_ClosedTabs.undoCloseTab(aIndex, aWhere);
  63.   };
  64.  
  65.   // clone autoreload popup
  66.   let popup = document.getElementById("autoreload_popup");
  67.   let clonePopup = popup.cloneNode(true);
  68.   clonePopup.removeAttribute("id");
  69.   let menu = document.getElementById("tm-autoreload_menu");
  70.   if (menu)
  71.     menu.appendChild(popup);
  72.   let tabMenu = document.getElementById("tm-autoreloadTab_menu");
  73.   if (tabMenu)
  74.     tabMenu.appendChild(clonePopup);
  75.  
  76.   // we eval navigator-toolbox customizeDone in TMP_delayedStartup
  77.   TMP_BrowserToolboxCustomizeDone();
  78.  
  79.   // Look for RSS/Atom News Reader
  80.   TMP_LookForRSS();
  81. }
  82.  
  83. // Create new items in the tab bar context menu
  84. function TM_creatMenuItems () {
  85.   // getBrowser() here is for Firefox 3 we get here before BrowserStartup
  86.   // from Firefox 3.5 window have getter for gBrowser
  87.   if (!getBrowser().tabContextMenu) {
  88.     gBrowser.tabContextMenu = document.getAnonymousElementByAttribute(gBrowser, "anonid", "tabContextMenu");
  89.   }
  90.   var tabContextMenu = gBrowser.tabContextMenu;
  91.   tabContextMenu.setAttribute("onpopuphidden", tabContextMenu.getAttribute("onpopuphidden") + "if (event.target == this) TM_hidePopup();");
  92.   tabContextMenu.addEventListener("popupshowing", Tm_checkTabClick, false);
  93.   tabContextMenu.addEventListener("popupshown", TMP_tabContextMenuShown, false);
  94.  
  95.   tabContextMenu.setAttribute("id", "menuedit-tabContextMenu");
  96.  
  97.   if (gIsFirefox35) {
  98.     // From Firefox 3.5.4pre we can not use anonymous menupopup from toolbar button
  99.     // this hack enable tabmix to use tab context menu from tablist tollbar button  
  100.     gBrowser.mTabContainer.parentNode.insertBefore(gBrowser.tabContextMenu, gBrowser.mTabContainer);
  101.  
  102.     // to be compatible with firefox 3.0 we use our on move tab to new window
  103.     // firefox don't have function to duplicate the tab to new windows
  104.     // look in gBrowser.duplicateInWindow  
  105.     let item = document.getElementById("context_openTabInWindow");
  106.     if (item) // make sure no one removed it before we do
  107.       tabContextMenu.removeChild(item);
  108.   }
  109.  
  110. //XXX we don't need this...
  111.   var separators = tabContextMenu.getElementsByTagName("xul:menuseparator");
  112.   for (let i = 0; i < separators.length; i++ ) {
  113.     separators[i].setAttribute("id", "original-separator-" + i);
  114.   }
  115.  
  116.   if (gIsFirefox37) {
  117.     // from Firefox 3.7 2009-09-11 there is gContextMenu.openLinkInCurrent in contentAreaContextMenu
  118.     // move our menu to that position
  119.     let openLinkInCurrent = document.getElementById("context-openlinkincurrent");
  120.     let tabmix_menu = document.getElementById("tm-openlinkhere");
  121.     openLinkInCurrent.parentNode.insertBefore(tabmix_menu, openLinkInCurrent);
  122.   }
  123.  
  124.   // update context_newTab attribute
  125.   var newTab = document.getElementById("context_newTab");
  126.   newTab.setAttribute("_newtab", newTab.getAttribute("label"));
  127.   newTab.setAttribute("_afterthis", document.getElementById("tm-separator").getAttribute("_afterthis"));
  128.   newTab.setAttribute("tmp_iconic", "menuitem-iconic tabs-newbutton tabs-newbutton-menu tmp-icon");
  129.   newTab.removeAttribute("xbl:inherits");
  130.  
  131.   // group the close-tab options together
  132.   var closeTab = document.getElementById("context_closeTab");
  133.   var closeOther = document.getElementById("context_closeOtherTabs");
  134.   tabContextMenu.insertBefore( closeTab, closeOther );
  135.  
  136.   var newMenuItems = ["tm-duplicateTab","tm-duplicateinWin","tm-detachTab","tm-mergeWindowsTab","tm-renameTab",
  137.                       "tm-copyTabUrl", "tm-autoreloadTab_menu", "tm-reloadOther","tm-reloadLeft","tm-reloadRight","tm-separator",
  138.                       "tm-undoCloseList","tm-separator-2",
  139.                       "tm-closeAllTabs","tm-closeSimilar","tm-closeLeftTabs","tm-closeRightTabs",
  140.                       "tm-docShell","tm-freezeTab","tm-protectTab","tm-lockTab"];
  141.  
  142.   var newMenuOrders = [ 1, 2, 3, 4, 5, 6,
  143.                         9, 11, 12, 13, 14,
  144.                         15, 16,
  145.                         18, 19, 21, 22,
  146.                         24, 25, 26, 27];
  147.  
  148.   // insert new menuitems and separators
  149.   for (let i = 0; i < newMenuItems.length; i++ ) {
  150.     var newMenuItem = document.getElementById(newMenuItems[i]);
  151.     tabContextMenu.insertBefore( newMenuItem, tabContextMenu.childNodes.item(newMenuOrders[i]));
  152.   }
  153.   // remove our empty popup
  154.   var popup = document.getElementById("extTabMixPopup");
  155.   popup.parentNode.removeChild(popup);
  156.  
  157.   // move context_undoCloseTab before tm-undoCloseList
  158.   var _undoCloseTab = document.getElementById("context_undoCloseTab");
  159.   _undoCloseTab.setAttribute("key", "key_undoCloseTab");
  160.   tabContextMenu.insertBefore(_undoCloseTab, document.getElementById("tm-undoCloseList"));
  161.   // we can't disable menus with command attribute
  162.   _undoCloseTab.removeAttribute("command");
  163.   _undoCloseTab.setAttribute("oncommand", "TMP_ClosedTabs.undoCloseTab();");  
  164.  
  165.   // insret IE Tab menu-items before Bookmakrs menu-items or at the end if origSep2 is null
  166.   if ("gIeTab" in window) {
  167.     var aFunction = "createTabbarMenu" in IeTab.prototype ? "createTabbarMenu" : "init";
  168.     if (aFunction in IeTab.prototype) {
  169.       eval("IeTab.prototype." + aFunction +" ="+IeTab.prototype[aFunction].toString().replace(
  170.            'tabbarMenu.insertBefore(document.getElementById("ietab-tabbar-sep"), separator);',
  171.            'separator = document.getElementById("original-separator-2"); $&'
  172.       ));
  173.     }
  174.   }
  175.  
  176.  // fix conflict with CookiePie extension
  177.   if ("cookiepieContextMenu" in window && !cookiepieContextMenu.initialized)
  178.     cookiepieContextMenu.init();
  179. }
  180.  
  181. function TMP_openDialog(panel) {
  182.   var tabmixOptionsWin = gWindowManager.getMostRecentWindow("mozilla:tabmixopt");
  183.   if (tabmixOptionsWin) {
  184.  
  185.     var appearanceWin = gWindowManager.getMostRecentWindow("mozilla:tabmixopt-appearance");
  186.     var filetypeWin = gWindowManager.getMostRecentWindow("mozilla:tabmixopt-filetype");
  187.  
  188.     if (!appearanceWin && !filetypeWin && panel > -1)
  189.       tabmixOptionsWin.TM_selectTab(panel);
  190.  
  191.     var incompatibleBox = tabmixOptionsWin.document.getElementById("incompatible");
  192.     var incompatibleStatus = incompatibleBox.collapsed;
  193.  
  194.     incompatibleBox.collapsed = getExtensions().length == 0;
  195.     if (incompatibleStatus != incompatibleBox.collapsed)
  196.       tabmixOptionsWin.sizeToContent();
  197.  
  198.     (appearanceWin || filetypeWin || tabmixOptionsWin).focus();
  199.   }
  200.   else {
  201.     if(panel > -1)
  202.       gTabmixPrefs.setIntPref('extensions.tabmix.selected_tab', panel);
  203.  
  204.     window.openDialog("chrome://tabmixplus/content/pref/pref-tabmix.xul", "Tab Mix Plus", "chrome,titlebar,toolbar,close,dialog=no");
  205.   }
  206. }
  207.  
  208. /*
  209.  *  functions to disable incompatible extensions
  210.  *  original code by mrtech local_install.js , code modified by onemen 2006-01-13
  211.  */
  212. function disableExtensions(aWindow) {
  213.    var warning_list = getExtensions();
  214.  
  215.    if (warning_list.length == 0) {
  216.       return true;
  217.    }
  218.  
  219.    try {
  220.       warning_list.sort();
  221.    } catch(ex) { }
  222.  
  223.    var i, extension, outStr = "";
  224.    for ( i = 0; i < warning_list.length; i++ ) {
  225.       extension = warning_list[i];
  226.       outStr += " - " + extension._name + " " + extension._version + "\n";
  227.    }
  228.  
  229.    var showatStart = gTabmixPrefs.getBoolPref("extensions.tabmix.disableIncompatible")
  230.    var chkBoxState = showatStart ? CHECKBOX_CHECKED : CHECKBOX_UNCHECKED;
  231.  
  232.    var bundleID = "tmp-string-bundle"
  233.    var _stingBundle = document.getElementById(bundleID);
  234.    var title = _stingBundle.getString("incompatible.title");
  235.    var msg = _stingBundle.getString("incompatible.msg0") + "\n"
  236.            + _stingBundle.getString("incompatible.msg1") + "\n\n" + outStr + "\n\n";
  237.    var chkBoxLabel = _stingBundle.getString("incompatible.chkbox.label");
  238.    var buttons = [SessionManager.setLabel("incompatible.button0", bundleID),
  239.                  SessionManager.setLabel("incompatible.button1", bundleID)];
  240.    buttons.push(SessionManager.setLabel("incompatible.button2", bundleID));
  241.  
  242.    var result = TM_PromptService([BUTTON_EXTRA1, HIDE_MENUANDTEXT, chkBoxState],[title, msg, "", chkBoxLabel, buttons.join("\n")], aWindow);
  243.    if (result.checked != showatStart) {
  244.       gTabmixPrefs.setBoolPref("extensions.tabmix.disableIncompatible", result.checked);
  245.       nsIPrefServiceObj.savePrefFile(null); // store the pref immediately
  246.    }
  247.  
  248.    if (result.button != BUTTON_CANCEL) {
  249.       var extensionManager = Components.classes["@mozilla.org/extensions/manager;1"]
  250.                              .getService(Components.interfaces.nsIExtensionManager);
  251.       for ( i = 0; i < warning_list.length; i++ ) {
  252.          extension = warning_list[i];
  253.          try{
  254.             extensionManager.disableItem(extension._guid);
  255.          } catch(e) {
  256.             tmLog("error while disabled " + extension._name)
  257.          }
  258.       }
  259.  
  260.       var dataSource = extensionManager.datasource.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
  261.       if (dataSource)
  262.          dataSource.Flush();
  263.  
  264.       if (result.button == BUTTON_EXTRA1 && canQuitApplication()) {
  265.          var appStartup = Components.interfaces.nsIAppStartup;
  266.          Components.classes["@mozilla.org/toolkit/app-startup;1"]
  267.             .getService(appStartup).quit(appStartup.eRestart | appStartup.eAttemptQuit);
  268.       }
  269.       else {
  270.          msg = _stingBundle.getString("incompatible.msg2");
  271.          buttons = ["", SessionManager.setLabel("sm.button.continue")].join("\n");
  272.          TM_PromptService([BUTTON_CANCEL, HIDE_MENUANDTEXT, HIDE_CHECKBOX],[title, msg, "", "", buttons], aWindow);
  273.       }
  274.  
  275.       return true;
  276.    }
  277.    return false;
  278. }
  279.  
  280. function getExtensions() {
  281.  
  282.    var guid_list = {};
  283.    /*
  284.     *  The following extensions are integrated or incompatible with Tab Mix Plus
  285.     *
  286.     *  Add extensions ID in lowercase.
  287.     */
  288.    guid_list['{00bdd586-51fb-4b06-9c23-af2fb7609bf3}'] = true;    //   Basics
  289.    guid_list['{b98719b3-76d6-4bec-aeed-3ab542b23bd7}'] = true;    //   BlankLast
  290.    guid_list['{47921160-3085-4023-a145-8ec466babfba}'] = true;    //   Click2Tab
  291.    guid_list['{b0f9cad2-ebae-4685-b518-d3d9b41ea183}'] = true;    //   Close Tab On Double Click
  292.    guid_list['ctc@clav.mozdev.org'] = true;                       //   CTC
  293.    guid_list['{61ed2a9a-39eb-4aaf-bd14-06dfbe8880c3}'] = true;    //   Duplicate Tab
  294.    guid_list['flowtabs'] = true;                                  //   Flowing Tabs
  295.    guid_list['{cd2b821e-19f9-40a7-ac5c-08d6c197fc43}'] = true;    //   FLST
  296.    guid_list['{68e5dd30-a659-4987-99f9-eaf21f9d4140}'] = true;    //   LastTab
  297.    guid_list['minit@dorando'] = true;                             //   MiniT
  298.    guid_list['minit-drag'] = true;                                //   miniT-drag
  299.    guid_list['minit-tabscroll@dorando'] = true;                   //   miniT-tabscroll
  300.    guid_list['new-tab-button-on-tab-bar@mikegoodspeed.com'] = true;   //   new tab button on tab bar
  301.    guid_list['{66E978CD-981F-47DF-AC42-E3CF417C1467}'] = true;    //   new tab homepage
  302.    guid_list['newtaburl@sogame.cat'] = true;                      //   NewTabURL
  303.    guid_list['{4b2867d9-2973-42f3-bd9b-5ad30127c444}'] = true;    //   Petite Tabbrowser Extensions
  304.    guid_list['{888d99e7-e8b5-46a3-851e-1ec45da1e644}'] = true;    //   ReloadEvery
  305.    guid_list['{aede9b05-c23c-479b-a90e-9146ed62d377}'] = true;    //   Reload Tab On Double-Click
  306.    guid_list['{492aa940-beaa-11d8-9669-0800200c9a66}'] = true;    //   Scrollable Tabs
  307.    guid_list['{eb922232-fd76-4eb0-bd5a-c1cba4238343}'] = true;    //   Single Window
  308.    guid_list['{149C6CC6-EC62-4ebd-B719-3C2E867930C7}'] = true;    //   Stack style tabs
  309.    guid_list['supert@studio17.wordpress.com'] = true;             //   superT
  310.    guid_list['tabbin'] = true;                                    //   Tab Bin
  311.    guid_list['{43520b8f-4107-4351-ac64-9bcc5eea24b9}'] = true;    //   Tab Clicking Options
  312.    guid_list['{bea6d1a7-882d-425f-bc75-944e0063ff3b}'] = true;    //   Tab Mix [original one]
  313.    guid_list['tabtowindow@sogame.cat'] = true;                    //   Tab to window
  314.    guid_list['tabx@clav.mozdev.org'] = true;                      //   Tab X
  315.    guid_list['{0b0b0da8-08ba-4bc6-987c-6bc9f4d8a81e}'] = true;    //   Tabbrowser Extensions
  316.    guid_list['{9b9d2aaa-ae26-4447-a7a1-633a32b19ddd}'] = true;    //   Tabbrowser Preferences
  317.    guid_list['tabdrag'] = true;                                   //   tabdrag-for-tablib
  318.    guid_list['tabfx@chaosware.net'] = true;                       //   TabFX
  319.    guid_list['tabsopenrelative@jomel.me.uk'] = true;              //   Tabs open ralative
  320.    guid_list['tablib'] = true;                                    //   tablib
  321.    guid_list['{328bbe91-cb86-40b0-a3fd-2b39969f9faa}'] = true;    //   Undo Close Tab
  322.    guid_list['undoclosetab@dorando'] = true;                      //   Undo Close Tab
  323.    guid_list['{99ec6690-8bb1-11da-a72b-0800200c9a66}'] = true;    //   Unread Tabs
  324.    // updated 2009-08-01
  325.    guid_list['undoclosedtabsbutton@supernova00.biz'] = true;      //   Undo closed button
  326.    guid_list['remove-new-tab-button@forerunnerdesigns.com'] = true;//   Remove new tab button
  327.    guid_list['last-tab-close-button@victor.sacharin'] = true;     //   Last tab close button
  328.  
  329.    function prop(elm, str) {
  330.       var arc = RDFService.GetResource("http://www.mozilla.org/2004/em-rdf#" + str);
  331.       var target = extensionDS.GetTarget(elm, arc, true);
  332.       if (target instanceof Components.interfaces.nsIRDFLiteral ||
  333.               target instanceof Components.interfaces.nsIRDFInt)
  334.          return target.Value;
  335.       return null;
  336.    }
  337.  
  338.    var RDFService = Components.classes["@mozilla.org/rdf/rdf-service;1"]
  339.                .getService(Components.interfaces.nsIRDFService);
  340.    var Container = Components.classes["@mozilla.org/rdf/container;1"]
  341.                .getService(Components.interfaces.nsIRDFContainer);
  342.    var extensionDS = Components.classes["@mozilla.org/extensions/manager;1"]
  343.                .getService(Components.interfaces.nsIExtensionManager).datasource;
  344.    var root = "urn:mozilla:item:";
  345.  
  346.    try { // in ff 1.0.x we can get error at startup
  347.       Container.Init(extensionDS, RDFService.GetResource(root + "root"));
  348.    } catch (e) {
  349.       tmLog("error in getExtensions " + e);
  350.       return [];
  351.    }
  352.  
  353.    var elements = Container.GetElements();
  354.    var extensionsArray = [];
  355.  
  356.    while (elements.hasMoreElements()) {
  357.       var element=elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
  358.       var id = element.Value.replace(root, "");
  359.       if (typeof guid_list[id.toLowerCase()] != "undefined") {
  360.          var opType = prop(element, "opType");
  361.          var disabled = prop(element, "userDisabled");
  362.          if ((!disabled && opType != "needs-disable" && opType != "needs-uninstall") ||
  363.              ( disabled && opType == "needs-enable")) {
  364.             var name = prop(element, "name");
  365.             name = name.charAt(0).toUpperCase() + name.substr(1);
  366.             extensionsArray.push({_name: name, _guid: id, _version:prop(element, "version")});
  367.          }
  368.       }
  369.    }
  370.    return extensionsArray;
  371. }
  372.  
  373. var TMP_eventListener = {
  374.   init: function TMP_EL_init(aTabContainer) {
  375.     window.addEventListener("load", this, false);
  376.  
  377.    /*
  378.     * Session Manager extesion add tabs too soon for us to check isTabVisible properly
  379.     * we get wrong scrollstatus at startup
  380.     * we add flag to use in tabBrowser.mTabContainer.isTabVisible
  381.     */
  382.     aTabContainer.setAttribute("SM_restart", true);
  383.  
  384.     aTabContainer.addEventListener("SSTabRestoring", this, true);
  385.     aTabContainer.addEventListener("SSTabClosing", this, true);
  386.     aTabContainer.addEventListener("TabOpen", this, true);
  387.     aTabContainer.addEventListener("TabClose", this, true);
  388.     aTabContainer.addEventListener("TabSelect", this, true);
  389.     // add event for mouse scrolling on tab bar, necessary for linux
  390.     aTabContainer.addEventListener("DOMMouseScroll", this, false);
  391.     if (/^Linux/.test(navigator.platform))
  392.        document.getElementById("navigator-toolbox").addEventListener("DOMMouseScroll", this, false);
  393.   },
  394.  
  395.   handleEvent: function TMP_EL_handleEvent(aEvent) {
  396.     switch (aEvent.type) {
  397.       case "SSTabRestoring":
  398.         this.onSSTabRestoring(aEvent);
  399.         break;
  400.       case "SSTabClosing":
  401.         this.onSSTabClosing(aEvent);
  402.         break;
  403.       case "TabOpen":
  404.         this.onTabOpen(aEvent);
  405.         break;
  406.       case "TabClose":
  407.         this.onTabClose(aEvent);
  408.         break;
  409.       case "TabSelect":
  410.         this.onTabSelect(aEvent);
  411.         break;
  412.       case "DOMMouseScroll":
  413.         this.onTabBarScroll(aEvent);
  414.         break;
  415.       case "load":
  416.         try {
  417.           this.onWindowOpen(aEvent);
  418.         } catch (ex) {TMP_ASSERT(ex);}
  419.         break;
  420.       case "unload":
  421.         this.onWindowClose(aEvent);
  422.         break;
  423.       case "fullscreen":
  424.         this.onFullScreen(false);
  425.         break;
  426.     }
  427.   },
  428.  
  429.   onWindowOpen: function TMP_EL_onWindowOpen() {
  430.     window.removeEventListener("load", this, false);
  431.     window.addEventListener("unload", this, false);
  432.     window.addEventListener("fullscreen", this, true);
  433.  
  434.     // don't load tabmix into undock sidebar opened by ezsidebar extension
  435.     var wintype = window.document.documentElement.getAttribute("windowtype");
  436.     if (wintype == "mozilla:sidebar") return;
  437.  
  438.     // replace old Settings.
  439.     // we must call this before any other tabmix function
  440.     gTMPprefObserver.updateSettings();
  441.  
  442.     // init tabmix functions
  443.     try {
  444.       tablib.init();
  445.     } catch (ex) {TMP_ASSERT(ex);}
  446.     try {
  447.       TMP_Places.init();
  448.     } catch (ex) {TMP_ASSERT(ex);}
  449.     try {
  450.       TM_init();
  451.     } catch (ex) {TMP_ASSERT(ex);}
  452.     try {
  453.       TMP_LastTab.init();
  454.     } catch (ex) {TMP_ASSERT(ex);}
  455.     try {
  456.       TMP_TBP_init();
  457.     } catch (ex) {TMP_ASSERT(ex);}
  458.     try {
  459.       TMP_DragAndDrop_init();
  460.     } catch (ex) {TMP_ASSERT(ex);}
  461.  
  462.     //this window open form _restoreTab we use it only when sessionStore is off
  463.     // we can drop this some day soon
  464.     if ("tabmix_afterTabduplicated" in window && window.tabmix_afterTabduplicated && "tabmix_duplicatData" in window && window.tabmix_duplicatData)
  465.       NW_waitForSessionHistory();
  466.  
  467.     var tabBar = gBrowser.mTabContainer;
  468.  
  469.     //temp fix for bug 347930 - change Tab strip to be a toolbar will landed
  470.     // look in calssic.css -moz-padding-start: 3px;
  471.     if (gisToolbarMode)
  472.       tabBar.setAttribute("toolbarmode", "true");
  473.  
  474.     // fix bug in new tab button on right extension when we use multi row
  475.     if ("newTabButtons" in window) {
  476.       var newbuttonRight = document.getAnonymousElementByAttribute(tabBar, "id", "tabs-newbutton-right");
  477.       var newbuttonEnd = document.getAnonymousElementByAttribute(tabBar, "id", "tabs-newbutton-end");
  478.       if (newbuttonRight && newbuttonEnd)
  479.          newbuttonEnd.parentNode.insertBefore(newbuttonRight, newbuttonEnd);
  480.     }
  481.  
  482.    /*
  483.     * Session Manager extesion add tabs too soon for us to check isTabVisible properly
  484.     * we get wrong scrollstatus at startup
  485.     * we add flag to use in tabBrowser.mTabContainer.isTabVisible
  486.     */
  487.     if ("gSessionManager" in window && TMP_SessionStore.isAfterRestart())
  488.       setTimeout(function (_tabBar) { _tabBar.removeAttribute("SM_restart"); }, 0, tabBar);
  489.     else
  490.       tabBar.removeAttribute("SM_restart");
  491.  
  492.     if (/^Mac/.test(navigator.platform)) {
  493.       tabBar.setAttribute("Mac", "true");
  494.      /*
  495.       * get Mac drop indicator marginBottom ,   Mac default thme have marginBottom: -24px
  496.       *
  497.       * with TreeStyleTab extension vertical tabbar mTabDropIndicatorBar.firstChild is null
  498.       */
  499.       var ib = gBrowser.mTabDropIndicatorBar;
  500.       if (ib && ib.firstChild) {
  501.         TabDNDObserver.marginBottom =
  502.               parseInt(window.getComputedStyle(ib.firstChild, null).marginBottom.replace("px", ""));
  503.       }
  504.     }
  505.  
  506.     var skin = gTabmixPrefs.getCharPref("general.skins.selectedSkin");
  507.     if (skin=="classic/1.0") {
  508.       if (/^Mac/.test(navigator.platform))
  509.         tabBar.setAttribute("classic", "v3Mac");
  510.       else if (/^Linux/.test(navigator.platform)) {
  511.         tabBar.setAttribute("classic", "v3Linux");
  512.         tabBar.setAttribute("platform", "linux");
  513.       }
  514.       else {
  515.         tabBar.setAttribute("classic", "v3");
  516.         tabBar.setAttribute("platform", "xp");
  517.       }
  518.     }
  519.     else { //XXX need to add theme list here
  520.       var themes = /^(iPoxRemix|Ie8fox|Vfox3)/;
  521.       if (themes.test(skin)) {
  522.         // add backgroundrepeat Attribute for theme for use in multi-row
  523.         tabBar.setAttribute("backgroundrepeat" , true);
  524.       }
  525.     }
  526.  
  527.     // for new tab icon on context menu
  528.     TMP_setItem("context_newTab", "platform", tabBar.getAttribute("platform"));
  529.  
  530.     if (gIsFirefox35)
  531.        tabBar.setAttribute("platform", "v35");
  532.  
  533.     /* Chromifox set tab-close-button to !important; */
  534.     if (skin == "cfxec") {
  535.       let sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
  536.       let uri = gIOService.newURI("chrome://tabmixplus/skin/themes/chromifox.css", null, null);
  537.       if (!sss.sheetRegistered(uri, sss.USER_SHEET))
  538.         sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
  539.     }
  540.  
  541.     // don't remove maybe some themes use this with Tabmix
  542.     tabBar.setAttribute("tabmix_firefox3" , true);
  543.  
  544.     // adjust attribute when we close 2nd tab (we left with only one) or when we open 2nd tab
  545.     if (numberOfWindows() > 1)
  546.       adjustOn2ndTab.closeButton(1);
  547.  
  548.     if (gSingleWindowMode)
  549.       gTMPprefObserver.setSingleWindowUI();
  550.  
  551.     gTMPprefObserver.setMenuIcons();
  552.     gTMPprefObserver.toggleKey("key_tm_slideShow", "extensions.tabmix.disableF8Key");
  553.     gTMPprefObserver.toggleKey("key_tm_toggleFLST", "extensions.tabmix.disableF9Key");
  554.     try {
  555.       gTMPprefObserver.createColorRules();
  556.     } catch (ex) {TMP_ASSERT(ex);}
  557.     gTMPprefObserver.tabCloseButton();
  558.     var position = tabxPrefs.getIntPref("newTabButton.position");
  559.     if (position != 0)
  560.       gTMPprefObserver.changeNewTabButtonSide(position);
  561.     TMP_ClosedTabs.setButtonType(tabxPrefs.getBoolPref("undoCloseButton.menuonly"));
  562.  
  563.     gHideTabBar = tabxPrefs.getIntPref("hideTabbar");
  564.    /*
  565.     *  In the first time TMP is running we need to match extensions.tabmix.hideTabbar to browser.tabs.autoHide.
  566.     *  extensions.tabmix.hideTabbar default is 1 "Hide tabbar when i have only one tab"
  567.     *  if browser.tabs.autoHide is false we need to make sure extensions.tabmix.hideTabbar is set to 0 "Never Hide tabbar:
  568.     */
  569.     if (!gTabmixPrefs.getBoolPref("browser.tabs.autoHide") && gHideTabBar == 1) {
  570.       gHideTabBar = 0;
  571.       tabxPrefs.setIntPref("hideTabbar", gHideTabBar);
  572.     }
  573.     else
  574.       gTMPprefObserver.setAutoHidePref();
  575.  
  576.     window.setTimeout(function () {
  577.       // initialize the value of "gTabBarWidth"
  578.       gTabBarWidth = gBrowser.mTabContainer.boxObject.width;
  579.       // only hide the tabbar after we catch the width
  580.       if (gHideTabBar == 2)
  581.         TMP_setStripVisibilityTo(false);
  582.     }, 100);
  583.  
  584.     var newPosition = tabxPrefs.getIntPref("tabBarPosition");
  585.     if (newPosition == 1)
  586.       gTMPprefObserver.tabBarPositionChanged(newPosition);
  587.     // In XP default theme alltabs-button is the highest object in the tab strip
  588.     // we need a place-holder for the height in case the user hide alltabs-buttin
  589.     var alltabsButton = document.getAnonymousElementByAttribute(tabBar, "anonid", "alltabs-button");
  590.     if (alltabsButton) {// mAllTabsButton removed from gBrowser in firefox 3.5 by bug 347930
  591.       var stripIsHidden = gTabmixPrefs.getBoolPref("browser.tabs.autoHide") && !gBrowser.getStripVisibility();
  592.       if (stripIsHidden)
  593.         gBrowser.setStripVisibilityTo(true);
  594.       var alltabsPlaceHolder = document.getAnonymousElementByAttribute(tabBar, "id", "alltabs-place-holder");
  595.       alltabsPlaceHolder.setAttribute("height", alltabsButton.parentNode.boxObject.height);
  596.       if (stripIsHidden)
  597.         gBrowser.setStripVisibilityTo(false);
  598.     }
  599.  
  600.     // make sure "extensions.tabmix.undoClose" is true if "browser.sessionstore.max_tabs_undo" is not zero
  601.     var sessionstoreUndoClose = gTabmixPrefs.getIntPref("browser.sessionstore.max_tabs_undo") > 0;
  602.     if (sessionstoreUndoClose != tabxPrefs.getBoolPref("undoClose"))
  603.       tabxPrefs.setBoolPref("undoClose", sessionstoreUndoClose);
  604.  
  605.     // progressMeter on tabs
  606.     var progressMeterOnTabs = TMP_getBoolPref(tabxBranch, "progressMeter", true);
  607.     tabBar.setAttribute("progressMeter", progressMeterOnTabs);
  608.     document.getElementById("statusbar-progresspanel").
  609.         setAttribute("hidden", TMP_getBoolPref(tabxBranch, "noprogress",false) && progressMeterOnTabs);
  610.  
  611.     TMupdateSettings(true);
  612.  
  613.     // tabmix Options in Tools menu
  614.     document.getElementById("tabmix-menu").hidden = !tabxPrefs.getBoolPref("optionsToolMenu");
  615.  
  616.     SessionManager.updateSettings();
  617.   },
  618.  
  619.   onSSTabRestoring: function TMP_EL_onSSTabRestoring(aEvent) {
  620.     var aTab = aEvent.target;
  621.  
  622.     if (aTab.hasAttribute("_locked")) {
  623.       if (aTab.getAttribute("_locked") == "true")
  624.         aTab.setAttribute("locked", "true");
  625.       else
  626.         aTab.removeAttribute("locked");
  627.     }
  628.  
  629.     // this function run before tab load, so onTabReloaded will run when onStateChange get STATE_STOP
  630.     var reloadData = aTab.getAttribute("reload-data");
  631.     if (reloadData) {
  632.       reloadData = reloadData.split(" ");
  633.       setupAutoReload(aTab);
  634.       aTab.autoReloadEnabled = true;
  635.       aTab.autoReloadURI = reloadData[0];
  636.       aTab.autoReloadTime = reloadData[1];
  637.     }
  638.   },
  639.  
  640.   onSSTabClosing: function TMP_EL_onSSTabClosing(aEvent) {
  641.     var aTab = aEvent.target;
  642.  
  643.     var browser = gBrowser.getBrowserForTab(aTab);
  644.     var iconURL = browser.mIconURL;
  645.     if (aTab.hasAttribute("busy") || aTab.getAttribute("image") != iconURL) {
  646.       aTab.removeAttribute("busy");
  647.       if (iconURL)
  648.         aTab.setAttribute("image", iconURL);
  649.       else if (!(/^https?:/.test(browser.currentURI.spec)))
  650.         gBrowser.useDefaultIcon(aTab);
  651.     }
  652.  
  653.     // fixed in sessionStore for firefox 3.5
  654.     if (!gIsFirefox35 && aTab.label == gBrowser.mStringBundle.getString("tabs.loading"))
  655.       gBrowser.setTabTitle(aTab);
  656.   },
  657.  
  658.   onFullScreen: function TMP_EL_onFullScreen(aPositionChanged) {
  659.     // add fullscr-bottom-toggler when tabbar is on the bottom
  660.     var fullScrToggler = document.getElementById("fullscr-bottom-toggler");
  661.     if (gTabbarPosition == 1 && (!window.fullScreen || aPositionChanged)) {
  662.       if (!fullScrToggler) {
  663.         fullScrToggler = document.createElement("toolbar");
  664.         fullScrToggler.id = "fullscr-bottom-toggler";
  665.         fullScrToggler.setAttribute("customizable", "false");
  666.         var _toolbox = document.createElement("toolbox");
  667.         _toolbox.appendChild(fullScrToggler);
  668.         gBrowser.mTabBox.insertBefore(_toolbox, gBrowser.mTabBox.firstChild);
  669.         eval("FullScreen.mouseoverToggle ="+FullScreen.mouseoverToggle.toString().replace(
  670.           'document.getElementById("fullscr-toggler").setAttribute("moz-collapsed", aShow);',
  671.           '$& \
  672.            document.getElementById("fullscr-bottom-toggler").setAttribute("moz-collapsed", aShow);'
  673.         ));
  674.       }
  675.       fullScrToggler.addEventListener("mouseover", FullScreen._expandCallback, false);
  676.       fullScrToggler.addEventListener("dragenter", FullScreen._expandCallback, false);
  677.       fullScrToggler.setAttribute("moz-collapsed", "false");
  678.       fullScrToggler.setAttribute("inFullscreen", "true");
  679.     }
  680.     else if (fullScrToggler && window.fullScreen) {
  681.       fullScrToggler.removeEventListener("mouseover", FullScreen._expandCallback, false);
  682.       fullScrToggler.removeEventListener("dragenter", FullScreen._expandCallback, false);
  683.       fullScrToggler.removeAttribute("inFullscreen");
  684.       if (FullScreen._isChromeCollapsed)
  685.         document.getElementById("fullscr-bottom-toggler").setAttribute("moz-collapsed", "true");
  686.     }
  687.   },
  688.  
  689.   // Function to catch when new tabs are created and update tab icons if needed
  690.   // In addition clicks and doubleclick events are trapped.
  691.   onTabOpen: function TMP_EL_onTabOpen(aEvent) {
  692.     var aTab = aEvent.target;
  693.  
  694.     // adjust attribute when we close 2nd tab (we left with only one) or when we open 2nd tab
  695.     adjustOn2ndTab.closeButton(1);
  696.  
  697.     var showCloseButton = tabxPrefs.getBoolPref("tabXMode.enable");
  698.     if (showCloseButton) {
  699.       var closeButtonOptions = ["no-button","always","showhover","current","current_hover","always"];
  700.       aTab.setAttribute("tabx", closeButtonOptions[addtabx]);
  701.     }
  702.  
  703.     if (tabxleft)
  704.       aTab.setAttribute("tabxleft", "on");
  705.  
  706.     if ( alwaysNewTab == 1 )
  707.       aTab.setAttribute("locked", "true");
  708.  
  709.     this.onTabOpen_updateTabBar();
  710.  
  711.     // the hack in TreeStyleTab extension look for our tabxTabAdded function
  712.     // we remove tabxTabAdded function and use TMP_eventListener.onTabOpen from 0.3.7pre.080815
  713.     if ("TreeStyleTabBrowser" in window && gBrowser.treeStyleTab) {
  714.       gBrowser.treeStyleTab.initTabAttributes(aTab);
  715.       gBrowser.treeStyleTab.initTabContentsOrder(aTab);
  716.     }
  717.   },
  718.  
  719.   // TGM extention use it
  720.   onTabOpen_updateTabBar: function TMP_EL_onTabOpen_updateTabBar() {
  721.     //XXX underline the label bleed over the end when tab is to small and we have close button on the tab !!!!????
  722.     if (!gBrowser.mTabContainer.hasAttribute("hideunderline") && !gBrowser.mTabContainer._timeout) {
  723.       gBrowser.mTabContainer._timeout = window.setTimeout( function(tabBar) {
  724.         toggleUnderlineTabsLabel();
  725.         if (tabBar._timeout) {
  726.           clearTimeout(tabBar._timeout);
  727.           tabBar._timeout = null;
  728.         }
  729.       }, 50, gBrowser.mTabContainer);
  730.     }
  731.  
  732.     if (gBrowser.mTabContainer.getAttribute("multibar") != "scrollbar")
  733.       tabBarScrollStatus();
  734.     checkBeforeAndAfter();
  735.   },
  736.  
  737.   onTabClose: function TMP_EL_onTabClose(aEvent) {
  738.     // aTab is the tab we are closing now
  739.     var aTab = aEvent.target;
  740.  
  741.     // adjust attribute when we close 2nd tab
  742.     adjustOn2ndTab.closeButton(2, aTab);
  743.  
  744.     var tabBar = gBrowser.mTabContainer;
  745.  
  746.     // if we close the 2nd tab and browser.tabs.autoHide is true reset all scroll and multi-row parameter
  747.     // strip already collapsed at this point
  748.     if (tabBar.childNodes.length == 2 && gTabmixPrefs.getBoolPref("browser.tabs.autoHide")) {
  749.       tabBar.collapsedTabs = 0;
  750.       setTabBarHeight(1);
  751.       tabBar.removeAttribute("multibar");
  752.     }
  753.  
  754.     this.onTabClose_updateTabBar(aTab);
  755.   },
  756.  
  757.   // TGM extention use it
  758.   onTabClose_updateTabBar: function TMP_EL_onTabClose_updateTabBar(aTab) {
  759.     var tabBar = gBrowser.mTabContainer;  
  760.     if ( tabscroll != 2 ) {
  761.       var _canScrollTabsLeft = tabBar.canScrollTabsLeft;
  762.       var _canScrollTabsRight = tabBar.canScrollTabsRight;
  763.       tabBar.collapsedTabs--;
  764.       if (!_canScrollTabsLeft)
  765.         tabBar.canScrollTabsLeft = false;
  766.       if (!_canScrollTabsRight)
  767.         tabBar.canScrollTabsRight = false;
  768.  
  769.       window.setTimeout( function() {
  770.                            tabBar.adjustScrollTabsLeft();
  771.                            tabBar.adjustScrollTabsRight();
  772.                            tabBar.adjustNewtabButtonvisibility();
  773.                          }, 50 );
  774.     }
  775.     else if (tabBar.hasAttribute("multibar")) {
  776.       // don't update tabBar.collapsedTabs after timeout
  777.       // we must do it live......
  778.       if (aTab._tPos < tabBar.collapsedTabs)
  779.         tabBar.collapsedTabs--;
  780.       if (!tabBar._onCloseTimeout) {
  781.         tabBar._onCloseTimeout = window.setTimeout( function TMP_onCloseTimeout() {
  782.           if (tabBar._onCloseTimeout) {
  783.             clearTimeout(tabBar._onCloseTimeout);
  784.             tabBar._onCloseTimeout = null;
  785.           }
  786.           tabBarScrollStatus();
  787.           checkBeforeAndAfter();
  788.         }, 100);
  789.       }
  790.     }
  791.     else if (tabBar.hasAttribute("disAllowNewtabbutton"))
  792.       tabBar.removeAttribute("disAllowNewtabbutton");
  793.  
  794.     //XXX underline the label bleed over the end when tab is to small and we have close button on the tab !!!!????
  795.     if (tabBar.hasAttribute("hideunderline"))
  796.       window.setTimeout( function() {toggleUnderlineTabsLabel();}, 50);
  797.  
  798.   },
  799.  
  800.   onTabSelect: function TMP_EL_TabSelect(aEvent) {
  801.     var tab = aEvent.target;
  802.     var tabBar = gBrowser.mTabContainer;
  803.     // update this functions after new tab select
  804.     tabBar.nextTab = 1;
  805.     tab.setAttribute("flst_id", new Date().getTime());
  806.     if (!tab.hasAttribute("visited"))
  807.       tab.setAttribute("visited", true);
  808.     TMP_LastTab.OnSelect();
  809.     SessionManager.tabSelected(true);
  810.  
  811.     if (tabBar.hasAttribute("multibar")) {
  812.       var top = tabBar.topTabY;
  813.       var tabRow = tabBar.getTabRowNumber(tab, top);
  814.       var prev = tab.previousSibling, next = tab.nextSibling;
  815.       if ( prev && tabRow != tabBar.getTabRowNumber(prev, top) )
  816.         prev.removeAttribute("beforeselected");
  817.       if ( next && tabRow != tabBar.getTabRowNumber(next, top) )
  818.         next.removeAttribute("afterselected");
  819.     }
  820.  
  821.     var tabsBottom = document.getAnonymousElementByAttribute(tabBar, "class", "tabs-bottom");
  822.     if (tabsBottom)
  823.       TMP_setItem(tabBar, "tabonbottom", tab.baseY >= tabsBottom.boxObject.y || null);
  824.   },
  825.  
  826.   onTabBarScroll: function TMP_EL_onTabBarScroll(aEvent) {
  827.     var tabBar = gBrowser.mTabContainer;
  828.  
  829.     for (var i = 0; i < tabBar.childNodes.length; i++)
  830.       tabBar.childNodes[i].setAttribute("showbutton","off");
  831.  
  832.     var ScrollDirection = aEvent.detail > 0 ? 1 : -1;
  833.       if (gTabmixPrefs.getBoolPref("extensions.tabmix.reversedScroll"))
  834.         ScrollDirection = -1 * ScrollDirection;
  835.  
  836.     var shouldMoveFocus = gTabmixPrefs.getBoolPref("extensions.tabmix.enableScrollSwitch");
  837.     if (shouldMoveFocus) {
  838.       tabBar.advanceSelectedTab(ScrollDirection, true);
  839.     }
  840.     else if ("TreeStyleTabBrowser" in window) {
  841.        return;
  842.     }
  843.     else if ( tabscroll != 2 )
  844.       tabBar.collapsedTabs += ScrollDirection;
  845.     else if ( tabscroll == 2 )
  846.       tabBar.rowScroll(ScrollDirection);
  847.  
  848.     aEvent.stopPropagation();
  849.     aEvent.preventDefault();
  850.   },
  851.  
  852.   onWindowClose: function TMP_EL_onWindowClose() {
  853.     window.removeEventListener("unload", this, false);
  854.  
  855.     if (!gIsFirefox35) {
  856.       gBrowser.mTabDropIndicatorBar.removeEventListener('dragover', TMP_TabDragOver, true);
  857.       gBrowser.mTabDropIndicatorBar.removeEventListener('dragdrop', TMP_TabDragDrop, true);
  858.     }
  859.  
  860.     document.getElementById("goPopup").removeEventListener("popupshowing", TMP_Places.historyMenuItemsTitle, false);
  861.  
  862.     var isLastWindow = numberOfWindows() == 0;
  863.     // we close tabmix dialog windows on exit
  864.     if (isLastWindow) {
  865.       Array.forEach(["tabmixopt-filetype", "tabmixopt-appearance", "tabmixopt"], function(aID) {
  866.         var win = gWindowManager.getMostRecentWindow("mozilla:" + aID);
  867.         if (win) {
  868.           if (aID != "tabmixopt")
  869.             win.close();
  870.           else
  871.             win.setTimeout(function(){win.close();},0);
  872.         }
  873.       });
  874.     }
  875.  
  876.     // check if we need to sanitize on exit without prompt to user
  877.     try {
  878.       // if tryToSanitize is false and privacy.sanitize.promptOnSanitize is true
  879.       // we call TMP_Sanitizer.sanitize from Firefox Sanitizer
  880.       var tabmixSanitized = isLastWindow && gTabmixPrefs.getBoolPref("privacy.sanitize.sanitizeOnShutdown") && TMP_Sanitizer.tryToSanitize(true);
  881.     }
  882.     catch (ex) {
  883.       tabmixSanitized = false;
  884.     }
  885.     if (!tabmixSanitized) {
  886.       SessionManager.deinit(isLastWindow, false);
  887.       SessionManager.windowIsClosing(true, isLastWindow, true, false);
  888.     }
  889.     if (gIsFirefox35) {
  890.       var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
  891.       observerService.notifyObservers(null, "browser-window-change-state", "closed");
  892.       observerService.removeObserver(SessionManager, "browser-window-change-state");
  893.       observerService.removeObserver(SessionManager, "private-browsing");
  894.       observerService.removeObserver(SessionManager, "quit-application-requested");
  895.       observerService.removeObserver(SessionManager, "browser-lastwindow-close-requested");       
  896.       if (SessionManager.afterExitPrivateBrowsing) {
  897.         clearTimeout(SessionManager.afterExitPrivateBrowsing);
  898.         SessionManager.afterExitPrivateBrowsing = null;
  899.       }
  900.     }
  901.  
  902.     document.getElementById("contentAreaContextMenu").removeEventListener("popupshowing", TM_checkContentMenu, false);
  903.     var tabContextMenu = gBrowser.mStrip.firstChild.nextSibling;
  904.     tabContextMenu.removeEventListener("popupshowing", Tm_checkTabClick, false);
  905.     tabContextMenu.removeEventListener("popupshown", TMP_tabContextMenuShown, false);
  906.  
  907.     TMP_LastTab.deinit();
  908.  
  909.     window.removeEventListener("fullscreen", this, true);
  910.     var fullScrToggler = document.getElementById("fullscr-bottom-toggler");
  911.     if (fullScrToggler) {
  912.       fullScrToggler.removeEventListener("mouseover", FullScreen._expandCallback, false);
  913.       fullScrToggler.removeEventListener("dragenter", FullScreen._expandCallback, false);
  914.     }
  915.  
  916.     gBrowser.mTabContainer.removeEventListener("SSTabRestoring", this, true);
  917.     gBrowser.mTabContainer.removeEventListener("SSTabClosing", this, true);
  918.     gBrowser.mTabContainer.removeEventListener("TabOpen", this, true);
  919.     gBrowser.mTabContainer.removeEventListener("TabClose", this, true);
  920.     gBrowser.mTabContainer.removeEventListener("TabSelect", this, true);
  921.     gBrowser.mTabContainer.removeEventListener("DOMMouseScroll", this, false);
  922.     if (/^Linux/.test(navigator.platform))
  923.       document.getElementById("navigator-toolbox").removeEventListener("DOMMouseScroll", this, false);
  924.  
  925.     // TreeStyleTab extension add this to be compatible with old tabmix version
  926.     // we call removeEventListener again here in case user close the window without opening new tabs
  927.     if ("TreeStyleTabBrowser" in window)
  928.       gBrowser.mTabContainer.removeEventListener('DOMNodeInserted', tabxTabAdded, true);
  929.  
  930.     gTMPprefObserver.removeObservers();
  931.   }
  932.  
  933. }
  934.  
  935. /* for treeStyleTab extension look in treeStyleTab hacks.js
  936.    we remove tabxTabAdded function and use TMP_eventListener.onTabOpen from 0.3.7pre.080815
  937. */
  938. function tabxTabAdded() {
  939.   // remove eventListener added by treeStyleTab on first call to tabxTabAdded
  940.   gBrowser.mTabContainer.removeEventListener('DOMNodeInserted', tabxTabAdded, true);
  941.   return;
  942. }
  943.